Optimize gtk_css_selector_match_all
authorMatthias Clasen <mclasen@redhat.com>
Wed, 9 Sep 2015 14:46:48 +0000 (10:46 -0400)
committerMatthias Clasen <mclasen@redhat.com>
Wed, 9 Sep 2015 15:17:13 +0000 (11:17 -0400)
We are dealing with really short lists here.
95% are < 10 matches, and the longest I've been able to record was 19.
So just do away with the hash table and do sorted insertion in
the array directly.

gtk/gtkcssselector.c

index 59e1404583310e07caee7b1dd66315e9effae622..760e6308475701d8be88424634bce9cbe0c8b2ce 100644 (file)
@@ -140,9 +140,27 @@ gtk_css_selector_tree_get_matches (const GtkCssSelectorTree *tree)
   return (gpointer *) ((guint8 *)tree + tree->matches_offset);
 }
 
+static void
+g_ptr_array_insert_sorted (GPtrArray *array,
+                           gpointer   data)
+{
+  gint i;
+
+  for (i = 0; i < array->len; i++)
+    {
+      if (data == array->pdata[i])
+        return;
+
+      if (data < array->pdata[i])
+        break;
+    }
+
+  g_ptr_array_insert (array, i, data);
+}
+
 static void
 gtk_css_selector_tree_found_match (const GtkCssSelectorTree *tree,
-                                  GHashTable *res)
+                                  GPtrArray                *array)
 {
   int i;
   gpointer *matches;
@@ -151,7 +169,7 @@ gtk_css_selector_tree_found_match (const GtkCssSelectorTree *tree,
   if (matches)
     {
       for (i = 0; matches[i] != NULL; i++)
-       g_hash_table_insert (res, matches[i], matches[i]);
+        g_ptr_array_insert_sorted (array, matches[i]);
     }
 }
 
@@ -1714,18 +1732,6 @@ gtk_css_selectors_skip_initial_selector (GtkCssSelector *selector, const GtkCssS
   return (GtkCssSelector *)gtk_css_selector_previous (selector);
 }
 
-static int
-direct_ptr_compare (const void *_a, const void *_b)
-{
-  gpointer *a = (gpointer *)_a;
-  gpointer *b = (gpointer *)_b;
-  if (*a < *b)
-    return -1;
-  else if (*a == *b)
-    return 0;
-  return 1;
-}
-
 static gboolean
 gtk_css_selector_tree_match_foreach (const GtkCssSelector *selector,
                                      const GtkCssMatcher  *matcher,
@@ -1751,28 +1757,15 @@ GPtrArray *
 _gtk_css_selector_tree_match_all (const GtkCssSelectorTree *tree,
                                  const GtkCssMatcher *matcher)
 {
-  GHashTable *res;
   GPtrArray *array;
-  GHashTableIter iter;
-  gpointer key;
 
   update_type_references ();
 
-  res = g_hash_table_new (g_direct_hash, g_direct_equal);
+  array = g_ptr_array_sized_new (16);
 
   for (; tree != NULL;
        tree = gtk_css_selector_tree_get_sibling (tree))
-    gtk_css_selector_foreach (&tree->selector, matcher, gtk_css_selector_tree_match_foreach, res);
-
-  array = g_ptr_array_sized_new (g_hash_table_size (res));
-
-  g_hash_table_iter_init (&iter, res);
-  while (g_hash_table_iter_next (&iter, &key, NULL))
-    g_ptr_array_add (array, key);
-
-  g_hash_table_destroy (res);
-
-  qsort (array->pdata, array->len, sizeof (gpointer), direct_ptr_compare);
+    gtk_css_selector_foreach (&tree->selector, matcher, gtk_css_selector_tree_match_foreach, array);
 
   return array;
 }